﻿#region Author

//// Yevhen Bobrov, http://blog.xtalion.com 

#endregion

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace Silverlight.Core.Infrastructure.Services
{
	public class AsyncServiceInterfaceFactory
	{
		static readonly Lazy<AsyncServiceInterfaceFactory> Singleton =
				new Lazy<AsyncServiceInterfaceFactory>(() => new AsyncServiceInterfaceFactory(), true);

		public static AsyncServiceInterfaceFactory Instance
		{
			get { return Singleton.Value; }
		}

		readonly ModuleBuilder _module;
		readonly Dictionary<Type, Type> _generated = new Dictionary<Type, Type>();

		public AsyncServiceInterfaceFactory()
		{
			var assemblyName = new AssemblyName("Silverlight.WCF.AutoGeneratedAsyncInterfaces");

			AppDomain appDomain = AppDomain.CurrentDomain;
			AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

			_module = assemblyBuilder.DefineDynamicModule("Silverlight.WCF.AutoGeneratedAsyncInterfaces.dll");
		}

		public Type Generate(Type syncInterface)
		{
			lock (_generated)
			{
				if (!_generated.ContainsKey(syncInterface))
					_generated[syncInterface] = GenerateAsyncInterface(syncInterface);

				return _generated[syncInterface];
			}
		}

		Type GenerateAsyncInterface(Type syncInterface)
		{
			var generator = new AsyncServiceInterfaceGenerator(_module, syncInterface);
			return generator.Generate();
		}
	}
}
